/* Copyright(C) 2006-2008 Dave Sexton  *
 * http://www.codeplex.com/aip         *
 * http://www.codeplex.com/aip/license *
 ***************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Configuration.Provider;
using DaveSexton.Web.Controls.Resources;

namespace DaveSexton.Web.Controls
{
	/// <summary>
	/// Specifies the names of embedded image resources that are used by <see cref="ResourceAutoInputProtectionImageProvider"/>.
	/// </summary>
	/// <include file='examples.xml' path='//example[@id="ImageResources"]'/>
	/// <seealso cref="ResourceAutoInputProtectionImageProvider"/>
	public enum AutoInputProtectionImageResource
	{
		/// <summary>
		/// A dark image with neon highlights.
		/// </summary>
		BlackNeon, 
		/// <summary>
		/// A medium toned image with a cloudy appearance.
		/// </summary>
		Cloudy, 
		/// <summary>
		/// An image with bright green and magenta tiles (mostly magenta).
		/// </summary>
		FuchsiaTile, 
		/// <summary>
		/// A bluish-green image with a webbed appearance.
		/// </summary>
		GreenWeb, 
		/// <summary>
		/// A medium toned image with orange and blue areas that appear scratched.
		/// </summary>
		OrangeBlueScratches
	}

	/// <summary>
	/// An implementation of <see cref="AutoInputProtectionImageProvider"/> that derives from <see cref="PartitionedAutoInputProtectionImageProvider"/>
	/// for creating instances of <see cref="PartitionedAutoInputProtectionImage"/> with a background that is loaded from an embedded resource in the AIP assembly.
	/// This class cannot be inherited.
	/// </summary>
	/// <remarks>
	/// <see cref="ResourceAutoInputProtectionImageProvider"/> is a factory that creates instances of <see cref="PartitionedAutoInputProtectionImage"/>.  Each 
	/// instance is randomly configured to use one of five embedded resource images as the surface image on which the text is rendered.
	/// </remarks>
	/// <include file='examples.xml' path='//example[@id="Resource"][@type="images"]'/>
	/// <include file='examples.xml' path='//example[@id="Resource"][@type="config"]'/>
	/// <seealso cref="AutoInputProtection.DefaultImageProvider"/>
	/// <seealso cref="Configuration.AutoInputProtectionSection"/>
	/// <seealso cref="AutoInputProtectionTextProvider"/>
	/// <seealso cref="AutoInputProtectionFilterProvider"/>
	/// <seealso cref="PartitionedAutoInputProtectionImage"/>
	/// <seealso cref="BackgroundAutoInputProtectionImage"/>
	public sealed class ResourceAutoInputProtectionImageProvider : PartitionedAutoInputProtectionImageProvider
	{
		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="ResourceAutoInputProtectionImageProvider" /> class.
		/// </summary>
		public ResourceAutoInputProtectionImageProvider()
		{
		}
		#endregion

		#region Methods
		/// <summary>
		/// Loads the provider's settings from the specified <paramref name="config"/>.
		/// </summary>
		/// <exception cref="ProviderException">Values exist that are not used by the provider.</exception>
		/// <param name="name">Name of the provider.</param>
		/// <param name="config">A collection of name and value pairs that will be used to initialize the provider.</param>
		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			if (config == null)
				throw new ArgumentNullException("config");

			if (String.IsNullOrEmpty(name))
				name = "ResourceAutoInputProtectionImageProvider";

			if (string.IsNullOrEmpty(config["description"]))
			{
				config.Remove("description");
				config.Add("description", "Resource-Based Auto-Input Protection Image Provider");
			}

			base.Initialize(name, config);

			// Throw an exception if unrecognized attributes remain
			if (config.Count > 0)
			{
				string attr = config.GetKey(0);

				if (!String.IsNullOrEmpty(attr))
					throw new ProviderException(string.Format(System.Globalization.CultureInfo.CurrentUICulture,
						Errors.UnrecognizedAttribute, attr));
			}
		}

		/// <summary>
		/// Creates an instance of a <see cref="PartitionedAutoInputProtectionImage"/> for the specified <paramref name="size"/> 
		/// and <paramref name="textProvider"/>, with a random surface image.
		/// </summary>
		/// <exception cref="ArgumentNullException">The specified <paramref name="textProvider"/> is <see langword="null"/>.</exception>
		/// <seealso cref="AutoInputProtection.GenerateAutoInputProtectionImage"/>
		/// <seealso cref="GenerateAutoInputProtectionImage(string,Size,AutoInputProtectionTextProvider)"/>
		/// <seealso cref="GenerateAutoInputProtectionImage(AutoInputProtectionImageResource,Size,AutoInputProtectionTextProvider)"/>
		/// <param name="size">The dimensions of the image.</param>
		/// <param name="textProvider"><see cref="AutoInputProtectionTextProvider"/> implementation to be used by the 
		/// <see cref="PartitionedAutoInputProtectionImage"/> that is created.</param>
		/// <returns>An instance of <see cref="PartitionedAutoInputProtectionImage"/> that can generate an image of the specified <paramref name="size"/> using 
		/// the specified <paramref name="textProvider"/>, with a random surface image.</returns>
		public override AutoInputProtectionImage GenerateRandomAutoInputProtectionImage(Size size, AutoInputProtectionTextProvider textProvider)
		{
			if (textProvider == null)
				throw new ArgumentNullException("textProvider");

			return GenerateAutoInputProtectionImage(ChooseRandomName(Enum.GetNames(typeof(AutoInputProtectionImageResource))), size, textProvider);
		}

		/// <summary>
		/// Creates an instance of a <see cref="PartitionedAutoInputProtectionImage"/> for the specified <paramref name="size"/> 
		/// and <paramref name="textProvider"/>, with a surface image that is the specified embedded <paramref name="resource"/>.
		/// </summary>
		/// <exception cref="System.ComponentModel.InvalidEnumArgumentException">The specified <paramref name="resource"/> is not a valid <see cref="AutoInputProtectionImageResource"/> value.</exception>
		/// <exception cref="ArgumentNullException">The specified <paramref name="name"/> or <paramref name="textProvider"/> is <see langword="null"/>.</exception>
		/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="size"/> is less than 1 by 1.</exception>
		/// <seealso cref="AutoInputProtection.GenerateAutoInputProtectionImage"/>
		/// <seealso cref="GenerateRandomAutoInputProtectionImage"/>
		/// <seealso cref="GenerateAutoInputProtectionImage(string,Size,AutoInputProtectionTextProvider)"/>
		/// <param name="resource">Specifies an embedded resouce in the AIP library to be used as the surface image.</param>
		/// <param name="size">The dimensions of the image.</param>
		/// <param name="textProvider"><see cref="AutoInputProtectionTextProvider"/> implementation to be used by the 
		/// <see cref="PartitionedAutoInputProtectionImage"/> that is created.</param>
		/// <returns>An instance of <see cref="PartitionedAutoInputProtectionImage"/> that can generate an image of the specified <paramref name="size"/> using 
		/// the specified <paramref name="textProvider"/>, with a surface image that is the specified embedded <paramref name="resource"/>.</returns>
		public AutoInputProtectionImage GenerateAutoInputProtectionImage(AutoInputProtectionImageResource resource, Size size, AutoInputProtectionTextProvider textProvider)
		{
			if (textProvider == null)
				throw new ArgumentNullException("textProvider");

			if (!Enum.IsDefined(typeof(AutoInputProtectionImageResource), resource))
				throw new System.ComponentModel.InvalidEnumArgumentException("resource", (int) resource, typeof(AutoInputProtectionImageResource));

			return GenerateAutoInputProtectionImage(resource.ToString(), size, textProvider);
		}

		/// <summary>
		/// Creates an instance of a <see cref="PartitionedAutoInputProtectionImage"/> for the specified <paramref name="size"/> 
		/// and <paramref name="textProvider"/>, with a surface image that is an emedded image resource of the specified <paramref name="name"/>.
		/// </summary>
		/// <exception cref="ArgumentNullException">The specified <paramref name="name"/> or <paramref name="textProvider"/> is <see langword="null"/>.</exception>
		/// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="size"/> is less than 1 by 1.</exception>
		/// <seealso cref="AutoInputProtection.GenerateAutoInputProtectionImage"/>
		/// <seealso cref="GenerateRandomAutoInputProtectionImage"/>
		/// <seealso cref="GenerateAutoInputProtectionImage(AutoInputProtectionImageResource,Size,AutoInputProtectionTextProvider)"/>
		/// <param name="name">The name of an embedded resource in the AIP library to be used as the surface image..</param>
		/// <param name="size">The dimensions of the image.</param>
		/// <param name="textProvider"><see cref="AutoInputProtectionTextProvider"/> implementation to be used by the 
		/// <see cref="PartitionedAutoInputProtectionImage"/> that is created.</param>
		/// <returns>An instance of <see cref="PartitionedAutoInputProtectionImage"/> that can generate an image of the specified <paramref name="size"/> using 
		/// the specified <paramref name="textProvider"/>, with a surface image that is an emedded image resource of the specified <paramref name="name"/>.</returns>
		public override AutoInputProtectionImage GenerateAutoInputProtectionImage(string name, Size size, AutoInputProtectionTextProvider textProvider)
		{
			if (name == null)
				throw new ArgumentNullException("name");

			if (textProvider == null)
				throw new ArgumentNullException("textProvider");

			if (size.Width < 1 || size.Height < 1)
				throw new ArgumentOutOfRangeException("size", size, Errors.SizePositiveIntRequired);

			Bitmap bitmap = (Bitmap) AutoInputProtectionImageResources.ResourceManager.GetObject(name);

			if (bitmap.Size != size)
				bitmap = new Bitmap(bitmap, size);

			return GenerateImage(bitmap, textProvider);
		}
		#endregion
	}
}
